# -*- coding: utf-8 -*-
import re
import base64
import requests
import win32con
import win32clipboard as clip
from io import BytesIO
from PIL import Image, ImageGrab
from requests.adapters import HTTPAdapter


# ==================== 图像处理 ==================== #
def load(address):
    """
    加载网络或本地图片（自动判断来源）
    :param address:
    :return:
    """
    try:
        pattern = re.compile(r'^(http)s?://', re.I)
        remote = pattern.match(address)
        if remote:
            s = requests.Session()
            s.mount('http://', HTTPAdapter(max_retries=3))
            s.mount('https://', HTTPAdapter(max_retries=3))
            response = s.get(address, timeout=(10, 15))
            buffer = BytesIO(response.content)
            im = Image.open(buffer)
        else:
            im = Image.open(address)
        return im
    except Exception as e:
        print(e)
        return None


def save(im, path):
    """
    保存图片
    :param im: 图像对象
    :param path: 保存路径
    :return:
    """
    try:
        im.save(path)
        return True
    except Exception as e:
        print(e)
        return False


def size(im):
    """
    获取图片大小
    :param im: 图像对象
    :return:
    """
    try:
        width, height = im.size
        return {'width': width, 'height': height}
    except Exception as e:
        print(e)
        return None


def resize(im, width, height):
    """
    改变图片大小
    :param im: 图像对象
    :param width: 图像宽度
    :param height: 图像高度
    :return:
    """
    try:
        out = im.resize((width, height))
        return out
    except Exception as e:
        print(e)
        return None


def remove_transparency(im, bg_colour=(255, 255, 255)):

    # Only process if image has transparency (http://stackoverflow.com/a/1963146)
    if im.mode in ('RGBA', 'LA') or (im.mode == 'P' and 'transparency' in im.info):

        # Need to convert to RGBA if LA format due to a bug in PIL (http://stackoverflow.com/a/1963146)
        alpha = im.convert('RGBA').split()[-1]

        # Create a new background image of our matt color.
        # Must be RGBA because paste requires both images have the same format
        # (http://stackoverflow.com/a/8720632  and  http://stackoverflow.com/a/9459208)
        bg = Image.new('RGBA', im.size, bg_colour + (255,))
        bg.paste(im, mask=alpha)
        return bg

    else:
        return im


def convert(im, mode='RGB'):
    """
    转换图片模式
    :param im: 图像对象
    :param mode: 图像模式
    :return:
    """
    try:
        # 如果目标色彩模式不包含透明通道,则去除透明并将透明色改为白色
        if mode not in ['RGBA', 'LA', 'P']:
            im = remove_transparency(im)
        out = im.convert(mode)
        return out
    except Exception as e:
        print(e)
        return None


def crop(im, coods=None):
    """
    裁剪图片
    :param im: 图像对象
    :param coods 裁剪图像的位置尺寸
    :return:
    """
    if coods is None:
        coods = {'left': 0, 'upper': 0, 'width': 0, 'height': 0}
    try:
        right = coods['left'] + coods['width']
        lower = coods['upper'] + coods['height']
        out = im.crop((coods['left'], coods['upper'], right, lower))
        return out
    except Exception as e:
        print(e)
        return None


def to_clip(im, width=0):
    """
    将图片放入剪贴板, 根据宽度等比例缩放图片大小
    :param im: 图片对象）
    :param width: 图片宽度
    :return:
    """
    try:
        # 等比例改变图片大小
        if width > 0:
            (x, y) = im.size  # read image size
            xs = width  # define standard width
            ys = y * xs / x  # calc height based on standard width
            im = im.resize((xs, ys), Image.ANTIALIAS)  # resize image with high-quality

        buffer = BytesIO()
        im.save(buffer, format="BMP")
        data = buffer.getvalue()[14:]
        buffer.close()

        # 往放入剪贴板放入二进制图片数据
        clip.OpenClipboard()
        clip.EmptyClipboard()
        clip.SetClipboardData(win32con.CF_DIB, data)
        clip.CloseClipboard()
        return True
    except Exception as e:
        print(e)
        return False


def screen_capture():
    """
    全屏截图
    :return:
    """
    try:
        capture = ImageGrab.grab()
        return capture
    except Exception as e:
        print(e)
        return None


def to_base64(im):
    """
    将图片转换为 base64 字符串
    :param im: 图像对象
    :return:
    """
    try:
        buffer = BytesIO()
        im.save(buffer, 'PNG')
        data = buffer.getvalue()
        buffer.close()
        return base64.b64encode(data).decode('utf-8')
    except Exception as e:
        print(e)
        return None


def from_base64(base64str):
    """
    将 base64 字符串转换为图像对象
    :param base64str: base64 图片字符串
    :return:
    """
    try:
        base64data = re.sub('^data:image/.+;base64,', '', base64str)
        data = base64.b64decode(base64data)
        buffer = BytesIO(data)
        im = Image.open(buffer)
        return im
    except Exception as e:
        print(e)
        return None


def show(im):
    im.show()


if __name__ == '__main__':
    print('MeImage - More Efficient UiBot Extension')

    # img = load('../_temp/sample.png')
    # img = load('https://via.placeholder.com/600x400.png/3021EC/FFFFFF?text=RpaPal+Image+Plugin')
    # show(img)
    #
    # save(img, '../_temp/sample_save.png')
    #
    # rsize = size(img)
    # print(rsize)
    #
    # outimg = resize(img, 100, 100)
    # show(outimg)
    #
    # for mode in ['1', 'L', 'P', 'RGB', 'RGBA', 'CMYK', 'YCbCr', 'I', 'F']:
    #     outimg = convert(img, mode)
    #     show(outimg)
    #
    # outimg = crop(img, {'left': 20, 'upper': 20, 'width': 40, 'height': 40})
    # show(outimg)
    #
    # to_clip(img)
    #
    # outimg = screen_capture()
    # show(outimg)

    # rbase64 = to_base64(img)
    # print(rbase64)

    # outimg = from_base64(rbase64)
    # outimg.show()
